﻿using ARSoft.Tools.Net.Dns;
using DomainNameServer.Models;
using DSVISUAL.LocalDNS;
using DSVISUAL.LocalDNS.Services;
using DSVISUAL.LocalDNS.Views;
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using static DSVISUAL.DnsProxy;
using static System.Windows.Forms.ListViewItem;

namespace DSVISUAL
{
    public partial class Form1 : Form
    {
        ConsoleForm f;
        List<IPAddress> dnsSetting;
        public Form1()
        {
            InitializeComponent();
            toolStripStatusLabel1.Text = "Set dns to 127.0.0.1 can enable functions.";
            this.notifyIcon1.MouseDoubleClick += new MouseEventHandler(notifyIcon1_MouseDoubleClick);
            this.notifyIcon1.Text = "LocalDNS";
            this.notifyIcon1.Visible = true;
            this.FormClosing += new FormClosingEventHandler(Form1_FormClosing);

            DnsProxy.Instance.QueryReceived += Instance_QueryReceived;
            this.listViewQueries.View = View.Details;
            this.listViewQueries.FullRowSelect = true;
            this.listViewQueries.Columns.Add("Index", 50);
            this.listViewQueries.Columns.Add("TransID", 60);
            this.listViewQueries.Columns.Add("LocalEndPoint", 120);
            this.listViewQueries.Columns.Add("DNS", 120);
            this.listViewQueries.Columns.Add("Spend(ms)", 60);
            this.listViewQueries.Columns.Add("Questions", 200);
            this.listViewQueries.Columns.Add("Level", 60);
            this.listViewQueries.Columns.Add("Answers", 300);
            comboBoxProxyMode.DropDownStyle = ComboBoxStyle.DropDownList;
            this.comboBoxProxyMode.DisplayMember = "Key";
            this.comboBoxProxyMode.ValueMember = "Value";
            this.comboBoxProxyMode.DataSource = EnumExtension.ToDictionary<ProxyMode>().ToList();

            foreach (var item in EnumExtension.ToDictionary<ProxyMode>())
            {
                var menuItem = new ToolStripMenuItem(item.Key)
                {
                    CheckOnClick = false,
                    Checked = false,
                    Tag = item.Value
                };
                menuItem.Click += MenuItem_Click;
                switchToToolStripMenuItem.DropDownItems.Add(menuItem);
            }
            this.comboBoxProxyMode.SelectedIndexChanged += ComboBoxProxyMode_SelectedIndexChanged;
            this.Load += new EventHandler(Form1_Load);

            showDnsSetting();
            this.comboBoxDns1.DisplayMember
                = this.comboBoxDns2.DisplayMember = "Provider";
            this.comboBoxDns1.ValueMember
                = this.comboBoxDns2.ValueMember = "Dns";


            comboBoxDns1.SelectedIndexChanged += ComboBoxDns1_SelectedIndexChanged;
            comboBoxDns2.SelectedIndexChanged += ComboBoxDns2_SelectedIndexChanged;

            this.comboBoxDns1.DataSource = PublicDns.List;
            this.comboBoxDns2.DataSource = PublicDns.List;
        }

        private void showDnsSetting()
        {
            dnsSetting = NetworkSetting.GetDnsList();
            if (!dnsSetting.Any())
            {
                dnsSetting = new List<IPAddress> { IPAddress.Loopback };
                NetworkSetting.SetDNS(new string[] { "127.0.0.1" });
            }
            this.labelDns1.Text = dnsSetting[0].ToString();
            if (dnsSetting.Count > 1)
            {
                this.labelDns2.Text = dnsSetting[1].ToString();
                this.labelDns2.Show();
            }
            else
            {
                this.labelDns2.Hide();
            }
        }

        private void MenuItem_Click(object sender, EventArgs e)
        {
            SetToolStripMenuItemChecked((sender as ToolStripMenuItem).Tag);
            this.comboBoxProxyMode.SelectedValue = (sender as ToolStripMenuItem).Tag;
        }

        private void ComboBoxDns2_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (comboBoxDns2.SelectedIndex != -1)
                DnsProxy.Instance.SetDNS2(IPAddress.Parse((comboBoxDns2.SelectedItem as PublicDns).DNS));
        }

        private void ComboBoxDns1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (comboBoxDns1.SelectedIndex != -1)
                DnsProxy.Instance.SetDNS1(IPAddress.Parse((comboBoxDns1.SelectedItem as PublicDns).DNS));
        }

        private void ComboBoxProxyMode_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (this.comboBoxProxyMode.SelectedValue != null)
            {
                Instance.Mode = (ProxyMode)this.comboBoxProxyMode.SelectedValue;
                SetToolStripMenuItemChecked(Instance.Mode);
                button3_MouseLeave(null, null);
            }
        }

        private void SetToolStripMenuItemChecked(object value)
        {
            foreach (ToolStripMenuItem item in switchToToolStripMenuItem.DropDownItems)
            {
                if (item.Tag.Equals((int)value))
                {
                    Instance.Mode = (ProxyMode)value;
                    item.Checked = true;
                }
                else
                {
                    item.Checked = false;
                }
            }
        }

        private void Instance_QueryReceived(object sender, MyQueryReceivedEventArgs e)
        {
            this.listViewQueries.BeginInvoke(new Action(() =>
            {
                try
                {
                    AppendListViewItem(e.EventArgs, e.ServerEndPoint, ((int)e.TimeElapsed.TotalMilliseconds).ToString());
                }
                catch (Exception ex)
                {
                    MessageBox.Show(this, ex.Message);
                }
            }));
        }

        private string GetDnsProvider(IPAddress ip)
        {
            var item = PublicDns.List.Find(x => x.DNS == ip.ToString());
            return item == null ? ip.ToString() : item.Provider;
        }
        MaxMindGeoIpService geoIp = new MaxMindGeoIpService();
        private void AppendListViewItem(QueryReceivedEventArgs e, IPEndPoint server, string elapsed)
        {
            var query = e.Query as DnsMessage;
            var queryText = string.Join(" | ", query.Questions.Select(q => q.RecordType + " " + q.Name));
            var domain = string.Join(" ", query.Questions.Select(q => q.Name));
            var response = e.Response as DnsMessage;
            if (response.ReturnCode != ReturnCode.NoError)
            {
                ListViewItem item = new ListViewItem();
                item.Text = this.listViewQueries.Items.Count.ToString();
                item.SubItems.Add(e.Query.TransactionID.ToString());
                item.SubItems.Add(e.RemoteEndpoint?.ToString());
                item.SubItems.Add(GetDnsProvider(server.Address));
                item.SubItems.Add(elapsed);
                item.SubItems.Add(queryText);
                item.SubItems.Add("Error");
                item.SubItems.Add(response.ReturnCode.ToString());
                item.Tag = new SearchContext { QueryText = domain, AnswerText = "", DNS = GetDnsProvider(server.Address) };
                this.listViewQueries.Items.Add(item);
                ListItemFilter(item);
            }
            else
            {
                var limit = GetRecordsLimit();
                bool aRecordOnly = aRecordOnlyToolStripMenuItem.Checked;
                int count = 0;
                foreach (var rr in response.AnswerRecords.OrderBy(x => x.RecordType))
                {
                    if (aRecordOnly && rr.RecordType != RecordType.A)
                    {
                        continue;
                    }
                    if (limit <= 0 || count < limit)
                    {
                        ListViewItem item = new ListViewItem();
                        item.Text = this.listViewQueries.Items.Count.ToString();
                        item.SubItems.Add(response.TransactionID.ToString());
                        item.SubItems.Add(e.RemoteEndpoint?.ToString());
                        item.SubItems.Add(GetDnsProvider(server.Address));
                        item.SubItems.Add(elapsed);
                        item.SubItems.Add(queryText);
                        item.SubItems.Add("Answer");

                        var ar = string.Join(" ", rr.ToString().Split(' ').Reverse().Take(2).Reverse());
                        var arr = (rr as ARecord);
                        if (arr != null)
                        {
                            var result = geoIp.ResolveIp(arr.Address.ToString()).ToLocation();
                            if (result != null)
                                ar = ar + " [" + result.ToString() + "]";
                        }
                        item.SubItems.Add(ar);
                        item.Tag = new SearchContext { QueryText = domain, AnswerText = ar, DNS = GetDnsProvider(server.Address) };
                        this.listViewQueries.Items.Add(item);
                        ListItemFilter(item);
                        count++;
                    }
                }
                foreach (var rr in response.AuthorityRecords)
                {
                    ListViewItem item = new ListViewItem();
                    item.Text = this.listViewQueries.Items.Count.ToString();
                    item.SubItems.Add(response.TransactionID.ToString());
                    item.SubItems.Add(e.RemoteEndpoint?.ToString());
                    item.SubItems.Add(GetDnsProvider(server.Address));
                    item.SubItems.Add(elapsed);
                    item.SubItems.Add(queryText);
                    item.SubItems.Add("Authority");
                    if (rr.RecordType == RecordType.Soa)
                    {
                        var soa = rr as SoaRecord;
                        item.SubItems.Add($"SOA {soa.MasterName}");

                        //从soa.MasterName查询DNS
                        //DnsProxy.Instance.QueryFromSOA(query.Questions[0].Name, soa.MasterName.ToString());
                    }
                    else
                        item.SubItems.Add(string.Join(" ", rr.ToString().Split(' ').Reverse().Take(2).Reverse()));
                    item.Tag = new SearchContext { QueryText = domain, AnswerText = "", DNS = GetDnsProvider(server.Address) };
                    this.listViewQueries.Items.Add(item);
                    ListItemFilter(item);
                }
                foreach (var rr in response.AdditionalRecords)
                {
                    var arr = (rr as AddressRecordBase);
                    var nsr = (rr as NsRecord);
                    var text = string.Empty;

                    if (arr != null)
                    {
                        text += arr.Address.ToString();
                        var result = geoIp.ResolveIp(arr.Address.ToString()).ToLocation();
                        if (result != null)
                            text = text + " [" + result.ToString() + "]";
                        queryText = arr.Name.ToString();
                    }
                    else if (nsr != null)
                    {
                        text += nsr.Name + " [" + nsr.NameServer + "]";
                    }
                    else if (rr is OptRecord)
                    {
                        text += rr.ToString() + " [" + rr.GetType().Name + "]";
                    }
                    ListViewItem item = new ListViewItem();
                    item.Text = this.listViewQueries.Items.Count.ToString();
                    item.SubItems.Add(response.TransactionID.ToString());
                    item.SubItems.Add(e.RemoteEndpoint?.ToString());
                    item.SubItems.Add(GetDnsProvider(server.Address));
                    item.SubItems.Add(elapsed);
                    item.SubItems.Add(queryText);
                    item.SubItems.Add("Additional");
                    item.SubItems.Add(text);
                    item.SubItems.Add(elapsed);

                    item.Tag = new SearchContext { QueryText = domain, AnswerText = text, DNS = GetDnsProvider(server.Address) };
                    this.listViewQueries.Items.Add(item);
                    ListItemFilter(item);
                }
            }
            if (autoScrollToolStripMenuItem.Checked)
            {
                try
                {
                    this.listViewQueries.EnsureVisible(listViewQueries.Items.Count - 1);
                }
                catch { }
            }

            if (this.listViewQueries.Items.Count > 500)
            {
                this.listViewQueries.Items.RemoveAt(0);
            }
        }

        void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            this.ShowInTaskbar = true;
            this.Visible = true;
            if (this.WindowState == FormWindowState.Minimized)
            {
                this.WindowState = FormWindowState.Normal;
            }
            this.Activate();
            this.Focus();
        }

        void Form1_Load(object sender, EventArgs e)
        {
            Instance.StateChanged += Instance_StateChanged;
            HookDnsRequestAndStartProxy();
            this.buttonStartStop.Text = Instance.IsProxyRuning ? "Stop Proxy Server" : "Start Proxy Server";
            var setting = StorageService.Instance.GetData<AppData>();
            if (setting == null)
            {
                setting = new AppData();
                StorageService.Instance.SaveData(setting);
            }
            if (setting != null)
            {
                comboBoxDns1.SelectedIndex = setting.DNS1;
                comboBoxDns2.SelectedIndex = setting.DNS2;
                switch (setting.RestoreBehavior)
                {
                    case DnsRestoreBehavior.Default:
                        radioButtonDnsDefault.Checked = true;
                        break;
                    case DnsRestoreBehavior.Public:
                        radioButtonPublicDns.Checked = true;
                        break;
                    case DnsRestoreBehavior.DHCP:
                        radioButtonDhcp.Checked = true;
                        break;
                    default:
                        break;
                }
                autoScrollToolStripMenuItem.Checked = setting.AutoScrollQueries;
                aRecordOnlyToolStripMenuItem.Checked = setting.ARecordsOnly;
                SetRecordsLimit(setting.RecordsLimit.ToString());
                var bindingSource = new BindingSource();
                bindingSource.DataSource = setting.DomainList ?? new List<DomainInfo>();
                DomainManager.Instance.SetDomains(bindingSource);
                this.comboBoxProxyMode.SelectedValue = setting.QueryMode;
                SetToolStripMenuItemChecked(setting.QueryMode);
            }
        }

        private void Instance_StateChanged(object sender, EventArgs e)
        {
            showDnsSetting();
            this.toolStripStatusLabel1.Text = Instance.IsProxyRuning ? "Server Runing" : "Server Stopped";
            this.enableProxyToolStripMenuItem.Text = this.buttonStartStop.Text = Instance.IsProxyRuning ? "Stop Proxy Server" : "Start Proxy Server";
        }

        void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason == CloseReason.WindowsShutDown)
            {
                ShouldExit = true;
            }
            //if (!ShouldExit)
            //{
            //    var ret = new ExitConfirmForm().ShowDialog(this);
            //    if (ret == DialogResult.Cancel)
            //    {
            //        e.Cancel = true;
            //        return;
            //    }
            //    else if (ret == DialogResult.Yes)
            //    {
            //        ShouldExit = true;
            //    }
            //}
            if (!ShouldExit)
            {
                e.Cancel = true;
                this.Visible = false;
                //this.notifyIcon1.ShowBalloonTip(150, this.Text, "Still runing here.", ToolTipIcon.None);
                //new ToolTip().Show("Still runing here.", );
                return;
            }
            this.Hide();
            StopProxyAndRestoreSystemProxy();
            PortMapService.StopAll();
        }

        private void HookDnsRequestAndStartProxy()
        {
            if (NetworkSetting.GetDnsList().All(x => x == IPAddress.Parse("127.0.0.1")))
            {
                return;
            }
            int retVal = NetworkSetting.SetDNS(new string[] { "127.0.0.1" });
            if (retVal == 91)
            {
                this.toolStripStatusLabel2.Text = "WARNING: Set System DNS to 127.0.0.1 failed, try as administrator.";
                this.toolStripStatusLabel2.ForeColor = Color.Red;
            }
            Instance.StartProxy();
            DnsFlushResolverCache();
            //Process.Start("cmd.exe", "/C ipconfig /flushdns");
        }

        private void StopProxyAndRestoreSystemProxy()
        {
            var appData = new AppData()
            {
                DomainList = DomainManager.Instance.GetDomains(),
                DNS1 = this.comboBoxDns1.SelectedIndex,
                DNS2 = this.comboBoxDns2.SelectedIndex,
                QueryMode = (int)this.comboBoxProxyMode.SelectedValue,
                RestoreBehavior = DnsRestoreBehavior.Default,
                AutoScrollQueries = autoScrollToolStripMenuItem.Checked,
                ARecordsOnly = aRecordOnlyToolStripMenuItem.Checked,
                RecordsLimit = GetRecordsLimit(),
            };
            if (radioButtonDhcp.Checked)
                appData.RestoreBehavior = DnsRestoreBehavior.DHCP;
            else if (radioButtonPublicDns.Checked)
                appData.RestoreBehavior = DnsRestoreBehavior.Public;

            StorageService.Instance.SaveData(appData);

            int retVal = 0;
            switch (appData.RestoreBehavior)
            {
                case DnsRestoreBehavior.Default:
                    retVal = NetworkSetting.SetDNS(dnsSetting.Select(x => x.ToString()).ToArray());
                    break;
                case DnsRestoreBehavior.Public:
                    retVal = NetworkSetting.SetDNS(new string[] { PublicDns.List[appData.DNS1].DNS, PublicDns.List[appData.DNS2].DNS });
                    break;
                case DnsRestoreBehavior.DHCP:
                    retVal = NetworkSetting.EnableDHCP();
                    break;
                default:
                    break;
            }
            Instance.StopProxy();
            DnsFlushResolverCache();
            if (retVal != 0)
            {
                if (NetworkSetting.GetDnsList().All(x => x != IPAddress.Parse("127.0.0.1")))
                {
                    return;
                }
                MessageBox.Show("Failed to restore System DNS setting", "WARNING");
            }
        }
        [DllImport("dnsapi.dll", EntryPoint = "DnsFlushResolverCache")]
        private static extern UInt32 DnsFlushResolverCache();
        private int GetRecordsLimit()
        {
            foreach (ToolStripMenuItem item in numberOfRecordsToolStripMenuItem.DropDownItems)
            {
                if (item.Checked)
                {
                    return int.Parse(item.Tag.ToString());
                }
            }
            return 0;
        }

        private void SetRecordsLimit(string value)
        {
            foreach (ToolStripMenuItem item in numberOfRecordsToolStripMenuItem.DropDownItems)
            {
                if (item.Tag.ToString() != value)
                {
                    item.Checked = false;
                }
                else
                {
                    item.Checked = true;
                }
            }
        }

        private void showMeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Visible = true;
            this.Activate();
        }

        private void killMeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ShouldExit = true;
            this.Close();
        }

        public static bool ShouldExit { get; set; }

        private void buttonFlushDns_Click(object sender, EventArgs e)
        {
            Process.Start("ipconfig /flushdns");
        }

        public void ExecuteCmd(string cmd)
        {
            if (f == null)
            {
                f = new ConsoleForm();
            }
            f.Visible = true;
            f.Input.WriteLine(cmd + "\r\n");
        }

        private void enableProxyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var toolStripMenuItem = sender as ToolStripMenuItem;
            if (DnsProxy.Instance.IsProxyRuning)
            {
                this.StopProxyAndRestoreSystemProxy();
                toolStripMenuItem.Text = "Start Proxy Server";
            }
            else
            {
                this.HookDnsRequestAndStartProxy();
                toolStripMenuItem.Text = "Stop Proxy Server";
            }
        }

        private void EditOrSave(TextBox textbox, Button btn)
        {
            var IsEditMode = !textbox.Enabled;
            textbox.Enabled = IsEditMode;
            btn.Text = IsEditMode ? "Save" : "Edit";

            Instance.SetDNS1(IPAddress.Parse(textbox.Text.Trim()));
        }

        private void buttonStartStop_Click(object sender, EventArgs e)
        {
            if (DnsProxy.Instance.IsProxyRuning)
            {
                StopProxyAndRestoreSystemProxy();

            }
            else
            {
                HookDnsRequestAndStartProxy();
            }

        }

        private void button1_Click_1(object sender, EventArgs e)
        {
            ShouldExit = true;
            this.Close();
        }

        private void clearHistoriesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.listViewQueries.Items.Clear();
        }
        private void button2_Click(object sender, EventArgs e)
        {
            var form = new DomainManagementForm();
            form.ShowDialog(this);
        }

        private void autoScrollToolStripMenuItem_Click(object sender, EventArgs e)
        {
            autoScrollToolStripMenuItem.Checked = !autoScrollToolStripMenuItem.Checked;
        }

        private void aRecordOnlyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            aRecordOnlyToolStripMenuItem.Checked = !aRecordOnlyToolStripMenuItem.Checked;
        }

        private void toolStripMenuItem2_Click(object sender, EventArgs e)
        {
            ItemsCheckOne(sender);
        }

        private void recordsMaxToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ItemsCheckOne(sender);
        }

        private void recordsMaxToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            ItemsCheckOne(sender);
        }

        private void unlimitedToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ItemsCheckOne(sender);
        }

        void ItemsCheckOne(object sender)
        {
            var current = sender as ToolStripMenuItem;
            if (current.Checked)
            {
                current.Checked = false;
            }
            else
            {
                var items = current.GetCurrentParent().Items;
                foreach (ToolStripMenuItem item in items)
                {
                    if (!item.Equals(sender) && item.Checked)
                    {
                        item.Checked = false;
                    }
                }
                current.Checked = true;
            }
        }

        private void button3_MouseHover(object sender, EventArgs e)
        {
            var tipText = "";
            switch (Instance.Mode)
            {
                case ProxyMode.LocalFirst:
                    tipText = "[LocalFirst] First query the DNS records you defined in this app, then query the public network DNS server's";
                    break;
                case ProxyMode.PublicFirst:
                    tipText = "[PublicFirst] First query DNS records on public network DNS servers, then query the DNS records you defined in this app";
                    break;
                case ProxyMode.LocalOnly:
                    tipText = "[LocalOnly] Query only DNS records on public network DNS servers";
                    break;
                case ProxyMode.PublicOnly:
                    tipText = "[PublicOnly] Query only the DNS records you defined in this app";
                    break;
                default:
                    break;
            }
            ToolTip tooltip = null;
            if (this.comboBoxProxyMode.Tag != null)
            {
                tooltip = (this.comboBoxProxyMode.Tag as ToolTip);
                tooltip.Hide(this.labelModeDescription);
            }
            else
            {
                tooltip = new ToolTip();
                tooltip.InitialDelay = 250;
                tooltip.AutoPopDelay = 2000;
            }
            this.comboBoxProxyMode.Tag = tooltip;
            tooltip.Show(tipText, this.labelModeDescription);
        }

        private void button3_MouseLeave(object sender, EventArgs e)
        {
            if (this.comboBoxProxyMode.Tag != null)
            {
                (this.comboBoxProxyMode.Tag as ToolTip).Hide(this.comboBoxProxyMode);
            }
        }

        private void button5_Click(object sender, EventArgs e)
        {
            MessageBox.Show("under dev");
        }

        private void exitEToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ShouldExit = true;
            this.Close();
        }

        private void dNSRecordsManagmentToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var form = new DomainManagementForm();
            form.ShowDialog(this);
        }

        private void aboutLocalDNSToolStripMenuItem_Click(object sender, EventArgs e)
        {
            new AboutBox1().ShowDialog();
            //Process.Start("https://github.com/kissstudio");
        }

        private void ListItemFilter(ListViewItem item)
        {
            if (string.IsNullOrEmpty(this.textBoxFilter.Text))
            {
                item.UseItemStyleForSubItems = true;
                item.ForeColor = SystemColors.WindowText;
                return;
            }
            foreach (ListViewSubItem subItem in item.SubItems)
            {
                subItem.ForeColor = SystemColors.WindowText;
            }

            var q = item.Tag as SearchContext;
            bool found = false;
            if (q.QueryText.Contains(this.textBoxFilter.Text))
            {
                item.SubItems[5].ForeColor = Color.OrangeRed;
                found = true;
            }
            if (q.AnswerText.Contains(this.textBoxFilter.Text))
            {
                item.SubItems[7].ForeColor = Color.OrangeRed;
                found = true;
            }
            if (q.DNS.Contains(this.textBoxFilter.Text))
            {
                item.SubItems[3].ForeColor = Color.OrangeRed;
                found = true;
            }
            if (found)
            {
                item.UseItemStyleForSubItems = false;
                item.ForeColor = SystemColors.WindowText;
            }
            else
            {
                item.UseItemStyleForSubItems = true;
                item.ForeColor = SystemColors.Control;
            }
        }

        private void textBoxFilter_TextChanged(object sender, EventArgs e)
        {
            foreach (ListViewItem item in this.listViewQueries.Items)
            {
                ListItemFilter(item);
            }
        }

        private void flusnSystemDnsCacheToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DnsFlushResolverCache();
            MessageBox.Show(this, "Operation Successful", this.Text);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            this.textBoxFilter.Text = "";
        }

        private void pORTMAPPToolStripMenuItem_Click(object sender, EventArgs e)
        {
            new PortMapConfigForm().ShowDialog(this);
        }

        private void button2_Click_1(object sender, EventArgs e)
        {
            var ds = PortMapService.LoadDataSource();
            var num = PortMapService.Start(ds);
            MessageBox.Show(this, $"{num} thread started/ {PortMapService.Listeners.Count} threads total", "PORT MAP SERVICE");
            PortMapService.SaveDataSource(ds);
        }
    }
    public class MyQueryReceivedEventArgs : EventArgs
    {
        public QueryReceivedEventArgs EventArgs { get; set; }
        public IPEndPoint ServerEndPoint { get; set; }
        public TimeSpan TimeElapsed { get; internal set; }
    }
}

